from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from carts.models import Carts
from users.models import Users
from goods.models import Goods
import redis


# Create your views here.
class AddCart(APIView):
    """
    添加购物车
    """

    def post(self, request):
        """
        思路:
        1,获取前端传来的user,productID
        2,根据用户名获取用户对象  根据商品id获取商品对象
        3,连接redis,准备加入数据库   构建hash  set  的key
            1,判断商品之前是否在redis中存在
                1,若存在,计算出之前的商品总数量,当前的总量+商品是数量是否大于库存数量
                    1,大于库存  不能购买 "code":202,"msg":"加购达到限购数量"
                    2,小于库存,购买,把之前的商品数量加1
                2,在redis中不存在,第一次加入  直接写入 hash   set
                3,其他
        """
        # `1
        username = request.data.get("user")
        print(username)
        pid = request.data.get("productID")
        # 2
        try:
            user = Users.objects.get(username=username)
        except Exception as e:
            print(e)
            return Response({"code": "204", 'msg': "用户不存在"})
        try:
            good = Goods.objects.get(id=pid)
        except Exception as e:
            print(e)
            return Response({"code": 204, 'msg': "商品不存在"})
        # 3
        rdb = redis.Redis()
        # 构建hash的key
        cart_key = "cart_%s" % user.id
        # 集合中的key
        cart_selected = "cart_selected_%s" % user.id

        # 默认商品数量
        count = 1
        # __1  判断商品的库存
        if good.stock > 0:
            # 有库存
            # 判断商品在redis中是否存在
            num = rdb.hget(cart_key, good.id)
            print("num>>>>>", num)
            if num:  # 在  购物车中此商品的总数量  是否大于库存
                good_count = int(num.decode())  # 原商品数量
                good_count += 1  # 新加购物车后的商品数量
                print("good_count>>>>>>>>>", good_count)
                # 判断此时商品数量是否大于库存
                if good_count > good.stock:
                    rdb.close()
                    return Response({"code": 202, 'msg': "数量达到限购数量!"})
                if good_count <= good.stock:
                    rdb.hset(cart_key, good.id, str(good_count))  # 写入哈希
                    rdb.sadd(cart_selected, good.id)  # 写入集合
                    # 断开redis
                    rdb.close()
                    return Response({"msg": "购物车已存在该商品,数量+1", "code": 201})
            else:
                # 没在  可直接添加
                rdb.hset(cart_key, good.id, str(count))  # 写入哈希
                rdb.sadd(cart_selected, good.id)  # 写入集合
                rdb.close()
                # 将添加的数据返回
                shopping_cart_data = {
                    'id': cart_key,
                    'productID': pid,
                    'productName': good.sku_name,
                    'productImg': good.img,
                    'price': good.selling_price,
                    'num': count,
                    'maxNum': good.stock,
                    'check': True,  # 默认加购
                }
                return Response({"code": 200, "msg": "添加购物车成功", "shoppingCartData": shopping_cart_data})
        else:
            # 无库存
            return Response({"code": 203, "msg": "库存    不足"})


# 获取购物车数据
class GetCart(APIView):
    def post(self, request):
        """
        1,获取用户信息


        """
        user = request.data.get("user")
        print("用户信息>>>>>>>>>>", user)
        # 用户信息>>>>>>>>>> {'userName': 'admin111', 'uid': 2}
        # 判断用户是否存在
        try:
            # 获取用户信息
            user_ = Users.objects.get(username=user["userName"])
            # 根据用户信息   构建哈希 集合  的key
            cart_key = "cart_%s" % user_.id  # hash 的 key
            cart_selected_key = "cart_selected_%s" % user_.id  # 集合的key
        except Exception as e:
            print(e)
            return Response({"msg": "用户不存在,请重新登录", "code": 204})
        # 查询当前用户购物车  即 哈希数据
        # 连接redis数据库
        redis_conn = redis.Redis()
        # 定义空商品列表
        shopping_cart_data = []
        # 购物车中勾选的商品  即集合中的数据  ,  使用列表推导式
        cart_selected = [int(i.decode()) for i in redis_conn.smembers(cart_selected_key)]
        # 遍历哈希 即购物车所有数据    items()   遍历字典的键(商品id)  与   值(商品数量)
        for good_id, count in redis_conn.hgetall(cart_key).items():
            good_id = int(good_id.decode())
            count = int(count.decode())
            # 判断商品   是否在  集合中  即 勾选状态
            if good_id in cart_selected:  # 商品被勾选  check=True
                one_good = get_one_good(cart_key, good_id, count, check=True)
            else:  # 商品未被勾选  check=True
                one_good = get_one_good(cart_key, good_id, count, check=False)
            # 将这些商品添加到商品列表中
            shopping_cart_data.append(one_good)
        # 返回响应 将商品列表返回
        return Response({"msg": "获取用户的购物车数据成功！", "code": 200, "shoppingCartData": shopping_cart_data})


# #把购物车里的每一个商品，组织成一个字典
def get_one_good(cart_key, good_id, count, check=False):
    """
    :param cart_key: 购物车id  也就是购物车的名字  hash名
    :param good_id: redis购物车(哈希)中一个商品的id,
    :param count: 该商品加购的数量
    :param check: 该商品是否被勾选
    :return: 一个商品的字典数据
    """
    # 根据商品id查询商品数据
    try:
        good = Goods.objects.get(id=good_id)
    except Exception as e:
        print(e)
        return {}
    return {
        "id": cart_key,
        "productID": good_id,
        "productName": good.sku_name,
        "productImg": good.img,
        "price": good.selling_price,
        "num": count,  # 该商品 在当前购物车中的数量
        "maxNum": good.stock,  # 限购数量
        "check": check,  # 购物车中该商品是否被勾选
    }


# 更新购物车商品数量
class UpdateCartNum(APIView):
    def post(self, request):
        # 获取前端传来的数据
        user = request.data.get("user")
        print("用户信息>>>>>>>>>>", user)
        pid = request.data.get("productID")
        num = request.data.get("num")
        # 用户信息>>>>>>>>>> {'userName': 'admin111', 'uid': 2}
        # 判断用户是否存在
        try:
            # 获取用户信息
            user_ = Users.objects.get(username=user["userName"])
            # 根据用户信息   构建哈希 集合  的key
            cart_key = "cart_%s" % user_.id  # hash 的 key
            cart_selected_key = "cart_selected_%s" % user_.id  # 集合的key
        except Exception as e:
            print(e)
            return Response({"msg": "用户不存在,请重新登录", "code": 204})
        # 连接redis数据库
        redis_conn = redis.Redis()
        try:
            # 更新商品数量
            # 被跟新的商品的状态设置为勾选
            redis_conn.sadd(cart_selected_key, pid)
            # 更新数据
            redis_conn.hset(cart_key, pid, num)
        except Exception as e:
            print(e)
            return Response({"msg": "更新失败", 'code': 400})
        return Response({"msg": "更新成功", 'code': 200})


# 更新购物车商品勾选状态  单选与取消单选
class UpdateCartStatus(APIView):
    def get(self, request):
        # 获取查询字符串中的数据
        cart_key = request.query_params.get("cartID")
        pid = request.query_params.get("productID")
        status = request.query_params.get("val")  # 接收的是修改后的状态
        # 通过购物车id来获取  集合名cart_selected_key
        cart_selected_key = "cart_selected_%s" % cart_key.split("_")[-1]
        # 连接数据库
        redis_conn = redis.Redis()
        # 要修改的是集合中的商品状态,
        if status == "true":  # 接收的是修改后的状态
            redis_conn.sadd(cart_selected_key, pid)
        else:
            redis_conn.srem(cart_selected_key, pid)
        redis_conn.close()
        return Response({"msg": "状态修改成功", "code": 200})


# 更新购物车商品勾选状态   全选  与  取消全选
class UpdateAllStatus(APIView):
    def put(self, request):
        cart_key = request.data.get("cartID")  # 购物车id
        status = request.data.get("val")  # 接受的是修改后的状态
        print("前端传来的数据", cart_key, status)
        # 通过购物车id得到集合名
        cart_selected_key = "cart_selected_%s" % cart_key.split("_")[-1]
        # 连接数据库
        redis_conn = redis.Redis()
        if status == "true":  # 接受的是修改后的状态
            # 获取索引商品id  并设置全选
            goods = redis_conn.hkeys(cart_key)  # 得到的是一个列表
            redis_conn.sadd(cart_selected_key, *goods)  # 使用*号可以得到列表中的每一个值  此为  解包
        else:  # 取消全选  删除勾选集合
            redis_conn.delete(cart_selected_key)
        redis_conn.close()
        return Response({"msg": "修改状态成功", "code": 200})


# 删除购物车中的商品
class DeleteCartView(APIView):
    def post(self, request):
        user = request.data.get("user")
        print("删除购物车数据>>>>接收user", user)
        pid = request.data.get("productID")
        try:
            user_ = Users.objects.get(username=user["userName"])
            # 构建哈希 和 集合名
            cart_key = "cart_%s" % user_.id
            cart_selected_key = "cart_selected_%s" % user_.id
        except Exception as e:
            print(e)
            return Response({"msg": "用户不存在,请重新登录尝试!"})
        try:
            # 连接redis
            redis_conn = redis.Redis()
            # 删除购物车中的数据
            redis_conn.hdel(cart_key, pid)
            # 删除勾选集合中的数据
            redis_conn.srem(cart_selected_key, pid)
            redis_conn.close()
        except Exception as e:
            print(e)
            return Response({"msg": "删除购物车失败,请刷新后尝试!", "code": 204})
        return Response({"msg": "删除成功", "code": 200})
